import { Md5 } from "ts-md5";

import {
  User,
  UserGateway,
  UserInterface,
  UserEmailGateway,
  UserSubInterface,
  postRefUserSubDto,
  UserWechatGateway,
  patchUserEmailDto,
  UserEmailInterface,
  UserPasswordGateway,
  UserWeChatInterface,
  doUserEmailLoginDto,
  doUserWeChatLoginDto,
  patchUserPasswordDto,
  UserPasswordInterface,
  doUserPasswordLoginDto,
} from "qqlx-core";

import { ViewBase, ViewBaseAction } from "@view/view-base";
import { UserSchema } from "@/stream/schema-user";

export class ViewUser
  extends ViewBase<User>
  implements ViewBaseAction<User>, UserInterface<{}>, UserSubInterface<{}>, UserWeChatInterface, UserPasswordInterface<{}>, UserEmailInterface
{
  private static instance: ViewUser;
  static getInstance(options?: { isSingleton?: boolean }) {
    if (options?.isSingleton === false) {
      return new ViewUser();
    }

    if (!this.instance) this.instance = new ViewUser();
    return this.instance;
  }

  private constructor() {
    super();
    this.initial();
    this.insertDefaultCondition();
  }

  getSchema(): User {
    return new UserSchema();
  }

  async get() {
    this.pending();
    return this.$request.get<null, { entity: User; withSubList: User[] }>(UserGateway.path);
  }

  async getList() {
    this.pending();
    return this.$request.get<null, { entity: User; withSubList: User[] }>(`${UserGateway.path}/list`);
  }

  async postRefUserSub(dto: postRefUserSubDto) {
    this.pending();
    const path = `${UserGateway.path}/sub`;
    return this.$request.post<postRefUserSubDto, null>(path, dto);
  }

  async doUserWeChatLogin(dto: doUserWeChatLoginDto) {
    this.pending();
    return this.$request.post<typeof dto, { SessionId: string }>(UserWechatGateway.path, dto);
  }

  async patchUserEmail(dto: patchUserEmailDto) {
    this.pending();
    return this.$request.patch<typeof dto, null>(UserEmailGateway.path, dto);
  }

  async doUserEmailLogin(dto: doUserEmailLoginDto) {
    this.pending();
    return this.$request.post<typeof dto, { SessionId: string }>(UserEmailGateway.path, dto);
  }

  async patchUserPassword(dto: patchUserPasswordDto) {
    this.pending();

    const password = new Md5().appendStr([dto.password, "QQLX"].join(";")).end() as string;
    return this.$request.patch<typeof dto, null>(UserPasswordGateway.path, { ...dto, password });
  }

  async doUserPasswordLogin(dto: doUserPasswordLoginDto) {
    this.pending();
    const password = new Md5().appendStr([dto.password, "QQLX"].join(";")).end() as string;
    return this.$request.post<typeof dto, { SessionId: string }>(UserPasswordGateway.path, { ...dto, password });
  }
}
